using System;
using System.ComponentModel.Composition;
using Caliburn.Micro;
using MediaOwl.Common.Busy;

namespace MediaOwl.Common.ViewModels
{
    [Export, PartCreationPolicy(CreationPolicy.NonShared)]
    public sealed class DialogBusyViewModel : Screen, IBusy
    {
        #region Fields

        private double target;

        #endregion

        #region Constructor

        private Exception busyError;

        public DialogBusyViewModel()
        {
            DisplayName = "Please wait...";
            target = 0;
        }

        #endregion

        #region Properties with Backing-Fields

        public Exception BusyError
        {
            get { return busyError; }
            set
            {
                busyError = value;
                NotifyOfPropertyChange(() => BusyError);
            }

        }

        private bool hasCancel;
        public bool HasCancel
        {
            get { return hasCancel; }
            private set
            {
                hasCancel = value;
                NotifyOfPropertyChange(() => HasCancel);
            }
        }

        public bool HasMessage
        {
            get
            {
                return !string.IsNullOrEmpty(BusyMessage);
            }
        }

        private string busyMessage;
        public string BusyMessage
        {
            get { return busyMessage; }
            set
            {
                busyMessage = value;
                NotifyOfPropertyChange(() => BusyMessage);
            }
        }

        public bool IsIndeterminate
        {
            get
            {
                return target <= 0;
            }
        }

        private double percentage;
        public double Percentage
        {
            get { return percentage; }
            private set
            {
                percentage = value;
                NotifyOfPropertyChange(() => Percentage);
            }
        }

        #endregion

        #region Methods

        public void WithData(string title, string message = null, bool withCancel = false)
        {
            DisplayName = title;

            BusyMessage = message;

            HasCancel = withCancel;

            NotifyOfPropertyChange(() => HasMessage);
        }

        public void WithTargetValue(double targetValue)
        {
            if (targetValue <= 0) return;

            target = targetValue;    
            UpdatePercentage(0);
            NotifyOfPropertyChange(() => IsIndeterminate);
        }

        public void UpdatePercentage(double currentValue)
        {
            Percentage = Math.Round(currentValue / target * 100, 0);
        }

        public void Cancel()
        {
            Canceled(this, new EventArgs());
        }

        public event EventHandler<EventArgs> Canceled = delegate { };

        #endregion
    }
}